<?php
    require_once APPLICATION_PATH . '/../../../lib/Doctrine/Common/ClassLoader.php';
    require_once APPLICATION_PATH . '/../../../lib/Doctrine/ODM/MongoDB/Mapping/Annotations/DoctrineAnnotations.php';
    define('DIR_FILES', realpath(dirname(__FILE__) . '/../../../public/sites/' . APPLICATION_NAME . '/assets/files') . '/');
    define('DIR_LIB', realpath(dirname(__FILE__) . '/../../../lib') . '/');
    define('DIR_OPT', realpath(dirname(__FILE__) . '/../../../data/sites/' . APPLICATION_NAME . '/options') . '/');
	define('DIR_CACHE', realpath(dirname(__file__) . '/../../../data/sites/' . APPLICATION_NAME . '/cache') . '/');
	define('DIR_FONTS', realpath(dirname(__file__) . '/../../../data/sites/' . APPLICATION_NAME . '/fonts') . '/');
	define('DIR_LOGS', realpath(dirname(__file__) . '/../../../data/sites/' . APPLICATION_NAME . '/logs') . '/');
	define('LOG_FILE', DIR_LOGS . 'logs.log');
    define('DIR_TMP', realpath(dirname(__file__) . '/../../../data/sites/' . APPLICATION_NAME . '/tmp') . '/');
    define('DIR_TRAD', realpath(dirname(__file__) . '/../../../data/sites/' . APPLICATION_NAME . '/trad') . '/');
    define('DIR_JDB', realpath(dirname(__file__) . '/../../../data/sites/' . APPLICATION_NAME . '/db') . '/');
    define('DIR_FLATDB', realpath(dirname(__file__) . '/../../../data/sites/' . APPLICATION_NAME . '/db') . '/');
    define('DIR_PLUGINS', APPLICATION_PATH . '/plugins/');
    define('DIR_FORMS', APPLICATION_PATH . '/forms/');
    define('DIR_HELPERS', APPLICATION_PATH . '/helpers/');
    define('DIR_LIBPROJECT', APPLICATION_PATH . '/lib/');
    define('DIR_SERVICES', APPLICATION_PATH . '/services/');
    define('DIR_MODELS', APPLICATION_PATH . '/models/');
    define('DIR_CONFIG', APPLICATION_PATH . '/configs/');

    use Doctrine\Common\ClassLoader,
    Doctrine\ODM\MongoDB\Mapping\Annotations as ODM,
    Doctrine\Common\Annotations\AnnotationReader,
    Doctrine\ODM\MongoDB\Configuration as MongoDBConfiguration,
    Doctrine\ODM\MongoDB\Mapping\Driver\AnnotationDriver,
    Doctrine\MongoDB\Connection as MongoDBConnection,
    Doctrine\ODM\MongoDB\DocumentManager,
    Doctrine\ORM\Configuration,
    Doctrine\ORM\EntityManager,
    Doctrine\Common\Cache\ArrayCache,
    Doctrine\DBAL\Logging\EchoSQLLogger;
        
    class App_bootstrap extends WZ_bootstrap
    {
        protected $_config;
        protected $_routes;
        
        public function _initError()
        {
            error_reporting(E_ALL);
            ini_set('display_errors', 'on');
            function WZErrorHandler($level, $message, $file, $line)
            {
                $level = $level & error_reporting();
                $dump = array(
                    'level' => $level,
                    'message' => $message,
                    'file' => $file,
                    'line' => $line
                );
                
                if ($level <> 0) {
                    var_dump($dump);
                } else {
                    return;
                }

                if (!defined('E_STRICT')) {
                    define('E_STRICT', 2048);
                }
                if (!defined('E_RECOVERABLE_ERROR')) {
                    define('E_RECOVERABLE_ERROR', 4096);
                }
                // if (!defined('E_DEPRECATED')) {
                    // define('E_DEPRECATED', 8192);
                // }
                // if (!defined('E_USER_DEPRECATED')) {
                    // define('E_USER_DEPRECATED', 16384);
                // }

                $errorMessage = '';

                switch($level){
                    case E_ERROR:
                        $errorMessage .= 'Error';
                        break;
                    case E_WARNING:
                        $errorMessage .= 'Warning';
                        break;
                    case E_PARSE:
                        $errorMessage .= 'Parse Error';
                        break;
                    case E_NOTICE:
                        $errorMessage .= 'Notice';
                        break;
                    case E_CORE_ERROR:
                        $errorMessage .= 'Core Error';
                        break;
                    case E_CORE_WARNING:
                        $errorMessage .= 'Core Warning';
                        break;
                    case E_COMPILE_ERROR:
                        $errorMessage .= 'Compile Error';
                        break;
                    case E_COMPILE_WARNING:
                        $errorMessage .= 'Compile Warning';
                        break;
                    case E_USER_ERROR:
                        $errorMessage .= 'User Error';
                        break;
                    case E_USER_WARNING:
                        $errorMessage .= 'User Warning';
                        break;
                    case E_USER_NOTICE:
                        $errorMessage .= 'User Notice';
                        break;
                    case E_STRICT:
                        $errorMessage .= 'Strict Notice';
                        break;
                    case E_RECOVERABLE_ERROR:
                        $errorMessage .= 'Recoverable Error';
                        break;
                    case E_DEPRECATED:
                        $errorMessage .= 'Deprecated functionality';
                        break;
                    case E_USER_DEPRECATED:
                        $errorMessage .= 'User-generated warning message';
                        break;
                    default:
                        $errorMessage .= "Unknown error ($level)";
                        break;
                }

                $errorMessage .= ": {$message}  in {$file} on line {$line}";
                \WZ::set('WZError', array($level, $errorMessage));
            }
            set_error_handler('WZErrorHandler');
        }
        
        public function _initApp()
        {
            try {
                \Zend_Session::start(true);
            } catch (\Exception $oException) {
                \Zend_Session::isRegenerated() || \Zend_Session::regenerateId();
                $_COOKIE = array();
            }
            \WZ::set('WZSession', new \Zend_Session_Namespace('WZSession'));
            $this->_config = \WZ::get('confApp')->confApp;
            $this->_routes = \WZ::get('confRoutes')->confRoutes;
            \WZ_Request::init();
            \WZ::urlSite();
            date_default_timezone_set($this->_config['app']['timezone']);
        }        
        
        public function _initTranslation()
        {
            $lng = (null === \WZ::get('WZlng')) ? $this->_config['app']['lng'] : \WZ::get('WZlng');
            $translate = new \Zend_Translate(
                array(
                    'adapter' => 'array',
                    'content' => DIR_TRAD . $lng . '.php',
                    'locale'  => $lng
                )
            );
            \WZ::set("WZTranslate", $translate);
        }
        
        public function _initCache()
        {
            $dbCache = DIR_CACHE . 'cacheApp.db';
            $frontendOptions = array(
                'caching' => true,
                'lifetime' => $this->_config['cache']['ttl'],
                'automatic_serialization' => $this->_config['cache']['automatic_serialization']
            );
            
            $cacheApp = \Zend_Cache::factory (
                'Core',
                'Sqlite',
                $frontendOptions,
                array ('cache_db_complete_path' => $dbCache)
            );
            
            $cache = new \WZ_Cache($cacheApp);
            
            \WZ::set('WZCacheApp', $cache);
        }
        
        public function _initDB()
        {
            $username   = $this->_config['resources']['db']['params']['username'];
            $password   = $this->_config['resources']['db']['params']['password'];
            $dbName     = $this->_config['resources']['db']['params']['dbname'];
            $host       = $this->_config['resources']['db']['params']['host'];
            
            $pdoParams  = array(\PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES UTF8;');

            $params = array(
                'host' => $host,
                'username' => $username,
                'password' => $password,
                'dbname' => $dbName,
                'driver_options' => $pdoParams
            );

            try {
                $db = \Zend_Db::factory('PDO_MYSQL', $params);
                \Zend_Db_Table_Abstract::setDefaultAdapter($db);
            } catch (\Exception $e) {
                die($e->getMessage());
            }
            $db->setFetchMode(\Zend_Db::FETCH_ASSOC);
            \WZ::set('ZendDb', $db);
        }
        
        public function _initDocument()
        {
            if (!extension_loaded('mongo')) {
                return null;
            }
            $autoloader = \Zend_Loader_Autoloader::getInstance();
            $classLoader = new ClassLoader('Doctrine\Common');
            $classLoader->register();

            $classLoader = new ClassLoader('Doctrine\ODM\MongoDB');
            $classLoader->register();

            $classLoader = new ClassLoader('Doctrine\MongoDB');
            $classLoader->register();

            $symfony = array(new ClassLoader('Symfony', APPLICATION_PATH . '/../../../lib/Doctrine'), 'loadClass');
            $autoloader->pushAutoloader($symfony, 'Symfony');

            $docs = array(new ClassLoader('Documents', APPLICATION_PATH . '/models'), 'loadClass');
            $autoloader->pushAutoloader($docs, 'Documents');

            $config = new MongoDBConfiguration();

            $config->setProxyDir(APPLICATION_PATH . '/models/Documents/Proxies');
            $config->setProxyNamespace('Proxies');

            $config->setHydratorDir(APPLICATION_PATH . '/models/Documents/Hydrators');
            $config->setHydratorNamespace('Hydrators');

            $config->setDefaultDB($this->_config['documents']['db']);
            
            $reader = new AnnotationReader();
            $config->setMetadataDriverImpl(new AnnotationDriver($reader, APPLICATION_PATH . '/models/Documents'));

            $dm = DocumentManager::create(new MongoDBConnection($this->_config['documents']['server']), $config);
            \WZ::set('dm', $dm);
            return $dm;
        }
        
        public function _initDoctrine()
        {
            $autoloader = \Zend_Loader_Autoloader::getInstance();
            $loader = new ClassLoader('Doctrine\ORM');
            $loader->register();
            $loader = new ClassLoader('Doctrine\Common');
            $loader->register();
            $loader = new ClassLoader('Doctrine\DBAL');
            $loader->register();
            $symfony = array(new ClassLoader('Symfony', APPLICATION_PATH . '/../../../lib/Doctrine'), 'loadClass');
            $autoloader->pushAutoloader($symfony, 'Symfony');
            $project = array(new ClassLoader($this->_config['doctrine']['className'], $this->_config['doctrine']['entityPath']), 'loadClass');
            $autoloader->pushAutoloader($project, 'Project');
            $services = new ClassLoader('Services', APPLICATION_PATH);
            $autoloader->pushAutoloader(array($services, 'loadClass'), 'Services');
            $proxiesClassLoader = new ClassLoader('Proxies', $this->_config['doctrine']['proxyPath']);
            $proxiesClassLoader->register();
            $classLoader = new ClassLoader('DoctrineExtensions', APPLICATION_PATH. "/../../../lib/Doctrine/DoctrineExtensions");
            $classLoader->register();

            // Set up caches
            $config = new Configuration;
            $cache = new ArrayCache;
            $config->setMetadataCacheImpl($cache);
            $driverImpl = new \Doctrine\ORM\Mapping\Driver\YamlDriver($this->_config['doctrine']['yamlPath']);
            $config->setMetadataDriverImpl($driverImpl);
            $config->setQueryCacheImpl($cache);

            // Proxy configuration
            $config->setProxyDir($this->_config['doctrine']['proxyPath']);
            $config->setProxyNamespace('Proxies');

            // Set up logger
            // $logger = new EchoSQLLogger;
            // $config->setSQLLogger($logger);

            $config->setAutoGenerateProxyClasses(0);

            // Database connection information
            
            $connectionOptions = array(
                'host' =>       $this->_config['resources']['db']['params']['host'],
                'port' =>       $this->_config['resources']['db']['port'],
                'user' =>       $this->_config['resources']['db']['params']['username'],
                'password' =>   $this->_config['resources']['db']['params']['password'],
                'dbname' =>     $this->_config['resources']['db']['params']['dbname'],
                'driver' =>     $this->_config['resources']['db']['adapter']
            );
            

            $em = EntityManager::create($connectionOptions, $config);
            \WZ::set('em', $em);
            return $em;
        }
        
        public function _initRoute()
        {
            $uri = \WZ::getUri();
            $route = \WZ_Route::getInstance();
            if (null === $uri) {
                $route->setModule($this->_routes['www_404']['defaults']['module']);
                $route->setController($this->_routes['www_404']['defaults']['controller']);
                $route->setAction($this->_routes['www_404']['defaults']['action']);
                $route->setFormat($this->_routes['www_404']['defaults']['format']);
            } elseif ($uri === 'home') {
                $route->setModule($this->_routes['www_index']['defaults']['module']);
                $route->setController($this->_routes['www_index']['defaults']['controller']);
                $route->setAction($this->_routes['www_index']['defaults']['action']);
                $route->setFormat($this->_routes['www_index']['defaults']['format']);
            } else {
                $routeUri = WZ_Route::getRoute($uri);
                $route->setModule($routeUri['module']);
                $route->setController($routeUri['controller']);
                $route->setAction($routeUri['action']);
                $route->setFormat($routeUri['format']);
                if (count($routeUri)) {
                    foreach ($routeUri as $key => $value) {
                        if ($key != 'module' && $key != 'controller' && $key != 'action' && $key != 'format' && !strstr($key, 'param')) {
                            $route->setParam($key, $value);
                        }
                    }
                }
            }
        }
        
        public function _initLog()
        {
            $writer = new \Zend_Log_Writer_Stream(LOG_FILE);
            $logger = new \Zend_Log();
            $logger->addWriter($writer);

            \WZ::set('WZLog', $logger);
        }
        
        
        
        public function _initUnitTest()
        {
            $eav = WZ_Eav::getInstance('test');
            $produit = $eav->create('product');
            // var_dump($produit);
            $produit->name = 'chien';
            $produit->price = 18;
            $produit->stock = 25;
            $produit->country = 'france';
            $p = $produit->save();
            var_dump($p);
            // $produits = $eav->select('produits', "prix > 10000 || pays LIKE '%a%'", 'pays', 'asc', 1);
            // $produits = $eav->select('produits');
            // $produit = $eav->create('produits');
            // $produit = $eav->selectByEntity(1);
            // $produit->prix = 18;
            // $produit->stock = 25;
            // $produit->pays = 'usa';
            // $produit->save();
            // var_dump($produit);
            // $produit->delete();
            // var_dump($produit);
            // var_dump($produits);
            // exit;
            
            // var_dump(\WZ::verify(5, 5));
            // $book = \WZService_Test_Book::find(6);
            // var_dump($book->getAuthor());exit;
            // $author = \WZService_Test_Author::find(4);
            // $author = new \WZModel_Test_Author;
            // $author->setLastname('Proust');
            // $author->setFirstname('Marcel');
            // $author = $author->save();
            // $book = new \WZModel_Test_Book;
            // $book->setAuthor($author);
            // $book->setTitle('Du côté de Guermantes');
            // $book->setYear(1921);
            // $book->save();
            // $book = new \WZModel_Test_Book;
            // $book->setAuthor($author);
            // $book->setTitle('Du côté de chez Swann');
            // $book->setYear(1922);
            // $book->save();
            // var_dump($author->getBooks());exit;
            // $author = new \WZCrud_Test_Author;
            // $book = new \WZCrud_Test_Book;
            // $sdb = \WZ_Simpledb::getInstance('testlightdb');
            // var_dump($sdb::getDb());exit;
            // $db = \WZ_Flatdb::getInstance('user');
            // $users = $db->select('age <= 51');
            // if (is_array($users)) {
                // foreach ($users as $user) {
                    // $age = $user->getAge();
                    // if ($age > 34) {
                        // $user->delete();
                    // }
                // }
            // } else if (is_object($users)) {
                // $user = $users;
                // $age = $user->getAge();
                // if ($age > 34) {
                    // $user->delete();
                // } else {
                    // var_dump($age);
                // }
            // }
            // $user = $db->newRow();
            // $user->setName('plusquellec');
            // $user->setFirstname('xavier');
            // $user->setAge(40);
            // $user->save();
            // var_dump(\wz::geoIpNearby());exit;
            // $user = new \WZModel_Test_User;
            // $user->setDatemodif();
            // $user->setRole();
            // $user->setLangue();
            // $user->setLogin('test');
            // $user->setActif();
            // $user->setMdp(md5('230278gp'));
            // var_dump($user->save());
            // var_dump(\WZ::curl('http://vod.zendpro.Com')->getBody());exit;
            // $request = \WZ_Request::getInstance();
            // $request->setParam('id', 1);
            // \WZ_Entity::getInstance();
            // $user = \WZ_Entity::find('Project\User', 4)->getName();
            // var_dump($user);
            // $table = 'users';
            // $db = \WZ_Db::getInstance($table);
            // $user = $db->find(7);
            // $user->setDatemodif($db->now());
            // $user->setLangue('it');
            // $user->setNom('Update');
            // $user->setLogin('machin ' . time());
            // $user->setNom('nom ' . time());
            // var_dump($user->save());
            // var_dump($user->save());
            // \WZ::vdump($db->find(7));
            // var_dump($auth);
            // var_dump(\WZ_Auth::isAuth());
            // var_dump(\WZ_Auth::logout());
            // var_dump(\WZ_Auth::isAuth());
            // var_dump(\WZ_Auth::logout());
            // exit;
            // var_dump(new \WZ_Request());
            // \WZ::getLogMessage(true);
            // $form = new \Zend_Form;
            // \WZ_Form::input($form, 'nom', 'Nom');
            // \WZ_Form::submit($form, 'submit', 'OK');
            // \WZ_Form::factory($form, 'index.php');
            // $renderForm = \WZ_Form::render($form);
            // echo $renderForm;
            // exit;
            // $page = \WZ::pagination(array());
            // \WZForm_Cache::getEcho();
            // $u = \WZ_Url::getUrl('www_test');
            // \wz::vdump($u);
            // $dm = \WZ::get('dm');
            // $d = new Documents\Account('gerald');
            // $dm->persist($d);
            // $dm->flush();
            // $d = $dm->getRepository('Documents\Account')->findOneByName('gerald');
            // \WZ::vdump($d);
        }
    }
    